package java5.io;

public class CalculoLoser implements Constantes {

    private UtilLoser util;
    private int[] casillasamenazadas;
    private int[] casillasamenazadasrival;
    private int[][] movimientos;
    private int[][] movimientosObligados;
    private int[][] defensas;
    private int[][] escondidas;

    public CalculoLoser(UtilLoser util) {
        this.util = util;
        casillasamenazadas = new int[100];
        casillasamenazadasrival = new int[100];
        movimientos = new int[50][4];
        movimientosObligados = new int[10][4];
        defensas = new int[60][4];
        escondidas = new int[5][10];
    }

    private void iniciarAmenazasEscondidas() {
        for (int i = 1; i < escondidas[0][0]; i++) {
            for (int j = 0; j < 10; j++) {
                escondidas[i][j] = 0;
            }
        }
        escondidas[0][0] = 1;
    }

    public int[][] devolverJugadas(int[] tablero, int jugador, int rival, int ini, int fin, boolean enroquecorto,
            boolean enroquelargo, boolean eslocal, int[] opc, int[] opc_rival) {
        int[][] jugadas;
        int[][] amenazasescondidas;
        boolean esObligatorio = false;
        int[] amenazasrival;
        int pos_king;
        int pos_jaque;
        int pking = opc[5];
        int[] esc;

        pos_king = util.devuelvePosicionRey(tablero, jugador);
        amenazasrival = this.devolverCasillasAmenazadas(tablero, rival, pking, opc_rival, false);
        amenazasescondidas = this.devolverCasillasAmenazadasEscondidas(tablero, rival, jugador, ini, fin, pos_king, opc_rival, opc);
        pos_jaque = util.esJaque(amenazasrival);

        if (pos_jaque != -1) {//si hay jaque
            jugadas = this.buscarJugadasenJaque(tablero, amenazasrival, jugador, ini, fin,
                    amenazasescondidas, pos_king, pos_jaque, rival, opc, opc_rival);
            if (eslocal) {
                if (jugadas[_cabeceraJugadas][_tieneJugadasObligatorias] == 1) {
                    jugadas = util.ordenarCapturas(jugadas, amenazasrival);
                } else if (jugadas[_cabeceraJugadas][_hayJaque] == 1) {
                    jugadas = util.ordenarJaque(jugadas, tablero, jugador);
                }
            }
        } else {
            int ficha;
            int cnt = 1;
            int cnto = 1;

            util.iniciarCabeceraJugada(movimientos[_cabeceraJugadas]);
            util.iniciarCabeceraJugada(movimientosObligados[_cabeceraJugadas]);

            for (int i = 0; i < 64; i++) {
                ficha = tablero[i];

                if (ficha * jugador > 0) {
                    esc = util.buscarIndiceAmenazaEscondida(amenazasescondidas, i);

                    if (esc != null && esc[sinMovimientos] == 1) {
                        continue;
                    }

                    if (ficha == opc[0]) {
                        switch (jugador) {
                            case white:
                                if (tablero[i + 8] == vacio && (esc == null || esc[verticalSuperior] == 1) && !esObligatorio) {
                                    if (i + 8 > 55 && i + 8 < 64) {
                                        this.ingresarJugada(movimientos[cnt++], PAWN, i, i + 8, QUEEN);
                                        this.ingresarJugada(movimientos[cnt++], PAWN, i, i + 8, ROOK);
                                        this.ingresarJugada(movimientos[cnt++], PAWN, i, i + 8, BISHOP);
                                        this.ingresarJugada(movimientos[cnt++], PAWN, i, i + 8, KNIGHT);
                                    } else {
                                        this.ingresarJugada(movimientos[cnt++], PAWN, i, i + 8, 0);
                                        if ((i >= 8 && i <= 15) && tablero[i + 16] == vacio) {
                                            this.ingresarJugada(movimientos[cnt++], PAWN, i, i + 16, 0);
                                        }
                                    }
                                }
                                if (i % 8 != 0 && (esc == null || esc[diagonalSuperiorIzquierda] == 1)) {
                                    if (tablero[i + 7] != vacio) {
                                        if (tablero[i + 7] > 0) {
                                            if (i + 7 > 55 && i + 7 < 64) {
                                                this.ingresarJugada(movimientosObligados[cnto++], PAWN, i, i + 7, QUEEN);
                                                this.ingresarJugada(movimientosObligados[cnto++], PAWN, i, i + 7, ROOK);
                                                this.ingresarJugada(movimientosObligados[cnto++], PAWN, i, i + 7, BISHOP);
                                                this.ingresarJugada(movimientosObligados[cnto++], PAWN, i, i + 7, KNIGHT);
                                            } else {
                                                this.ingresarJugada(movimientosObligados[cnto++], PAWN, i, i + 7, 0);
                                            }
                                            esObligatorio = true;
                                        }
                                    } else {
                                        if (ini != -1 && fin != -1 && tablero[fin] == pawn) {
                                            if (ini >= 48 && ini <= 55 && fin == ini - 16 && fin == i - 1) {
                                                esObligatorio = true;
                                                this.ingresarJugada(movimientosObligados[cnto++], PAWN, i, i + 7, 0);
                                            }
                                        }
                                    }
                                }
                                if ((i + 1) % 8 != 0 && (esc == null || esc[diagonalSuperiorDerecha] == 1)) {
                                    if (tablero[i + 9] != vacio) {
                                        if (tablero[i + 9] > 0) {
                                            if (i + 9 > 55 && i + 9 < 64) {
                                                this.ingresarJugada(movimientosObligados[cnto++], PAWN, i, i + 9, QUEEN);
                                                this.ingresarJugada(movimientosObligados[cnto++], PAWN, i, i + 9, ROOK);
                                                this.ingresarJugada(movimientosObligados[cnto++], PAWN, i, i + 9, BISHOP);
                                                this.ingresarJugada(movimientosObligados[cnto++], PAWN, i, i + 9, KNIGHT);
                                            } else {
                                                this.ingresarJugada(movimientosObligados[cnto++], PAWN, i, i + 9, 0);
                                            }
                                            esObligatorio = true;
                                        }
                                    } else {
                                        if (ini != -1 && fin != -1 && tablero[fin] == pawn) {
                                            if (ini >= 48 && ini <= 55 && fin == ini - 16 && fin == i + 1) {
                                                this.ingresarJugada(movimientosObligados[cnto++], PAWN, i, i + 9, 0);
                                                esObligatorio = true;
                                            }
                                        }
                                    }
                                }
                                break;
                            case black:
                                if (tablero[i - 8] == vacio && (esc == null || esc[verticalInferior] == 1) && !esObligatorio) {
                                    if (i - 8 >= 0 && i - 8 < 8) {
                                        this.ingresarJugada(movimientos[cnt++], pawn, i, i - 8, queen);
                                        this.ingresarJugada(movimientos[cnt++], pawn, i, i - 8, rook);
                                        this.ingresarJugada(movimientos[cnt++], pawn, i, i - 8, bishop);
                                        this.ingresarJugada(movimientos[cnt++], pawn, i, i - 8, knight);
                                    } else {
                                        this.ingresarJugada(movimientos[cnt++], pawn, i, i - 8, 0);
                                        if ((i >= 48 && i <= 55) && tablero[i - 16] == vacio) {
                                            this.ingresarJugada(movimientos[cnt++], pawn, i, i - 16, 0);
                                        }
                                    }
                                }
                                if ((i + 1) % 8 != 0 && (esc == null || esc[diagonalInferiorDerecha] == 1)) {
                                    if (tablero[i - 7] != vacio) {
                                        if (tablero[i - 7] < vacio) {
                                            if (i - 7 > 0 && i - 7 < 8) {
                                                this.ingresarJugada(movimientosObligados[cnto++], pawn, i, i - 7, queen);
                                                this.ingresarJugada(movimientosObligados[cnto++], pawn, i, i - 7, rook);
                                                this.ingresarJugada(movimientosObligados[cnto++], pawn, i, i - 7, bishop);
                                                this.ingresarJugada(movimientosObligados[cnto++], pawn, i, i - 7, knight);

                                            } else {
                                                this.ingresarJugada(movimientosObligados[cnto++], pawn, i, i - 7, 0);
                                            }
                                            esObligatorio = true;
                                        }
                                    } else {
                                        if (ini != -1 && fin != -1 && tablero[fin] == PAWN) {
                                            if (ini >= 8 && ini <= 15 && fin == ini + 16 && fin == i + 1) {
                                                this.ingresarJugada(movimientosObligados[cnto++], pawn, i, i - 7, 0);
                                                esObligatorio = true;
                                            }
                                        }
                                    }
                                }
                                if (i % 8 != 0 && (esc == null || esc[diagonalInferiorIzquierda] == 1)) {
                                    if (tablero[i - 9] != vacio) {
                                        if (tablero[i - 9] < vacio) {
                                            if (i - 9 >= 0 && i - 9 < 8) {
                                                this.ingresarJugada(movimientosObligados[cnto++], pawn, i, i - 9, queen);
                                                this.ingresarJugada(movimientosObligados[cnto++], pawn, i, i - 9, rook);
                                                this.ingresarJugada(movimientosObligados[cnto++], pawn, i, i - 9, bishop);
                                                this.ingresarJugada(movimientosObligados[cnto++], pawn, i, i - 9, knight);
                                            } else {
                                                this.ingresarJugada(movimientosObligados[cnto++], pawn, i, i - 9, 0);
                                            }
                                            esObligatorio = true;
                                        }
                                    } else {
                                        if (ini != -1 && fin != -1 && tablero[fin] == PAWN) {
                                            if (ini >= 8 && ini <= 15 && fin == ini + 16 && fin == i - 1) {
                                                this.ingresarJugada(movimientosObligados[cnto++], pawn, i, i - 9, 0);
                                                esObligatorio = true;
                                            }
                                        }
                                    }
                                }
                                break;
                        }
                        movimientos[_cabeceraJugadas][_cantidadJugadas] = cnt;
                        movimientosObligados[_cabeceraJugadas][_cantidadJugadas] = cnto;
                    } else if (ficha == opc[1]) {
                        //+6 -6
                        if (i < 56 && i % 8 > 1) {
                            if (tablero[i + 6] == vacio) {
                                if (!esObligatorio) {
                                    this.ingresarJugada(movimientos[cnt++], opc[1], i, i + 6, 0);
                                }
                            } else if (tablero[i + 6] * jugador < vacio) {
                                this.ingresarJugada(movimientosObligados[cnto++], opc[1], i, i + 6, 0);
                                esObligatorio = true;
                            }
                        }
                        if (i > 7 && i % 8 < 6) {
                            if (tablero[i - 6] == vacio) {
                                if (!esObligatorio) {
                                    this.ingresarJugada(movimientos[cnt++], opc[1], i, i - 6, 0);
                                }
                            } else if (tablero[i - 6] * jugador < vacio) {
                                this.ingresarJugada(movimientosObligados[cnto++], opc[1], i, i - 6, 0);
                                esObligatorio = true;
                            }
                        }
                        //+10 -10
                        if (i < 56 && i % 8 < 6) {
                            if (tablero[i + 10] == vacio) {
                                if (!esObligatorio) {
                                    this.ingresarJugada(movimientos[cnt++], opc[1], i, i + 10, 0);
                                }
                            } else if (tablero[i + 10] * jugador < vacio) {
                                this.ingresarJugada(movimientosObligados[cnto++], opc[1], i, i + 10, 0);
                                esObligatorio = true;
                            }
                        }
                        if (i > 7 && i % 8 > 1) {
                            if (tablero[i - 10] == vacio) {
                                if (!esObligatorio) {
                                    this.ingresarJugada(movimientos[cnt++], opc[1], i, i - 10, 0);
                                }
                            } else if (tablero[i - 10] * jugador < vacio) {
                                this.ingresarJugada(movimientosObligados[cnto++], opc[1], i, i + -10, 0);
                                esObligatorio = true;
                            }
                        }
                        //+15 -15
                        if (i < 48 && i % 8 > 0) {
                            if (tablero[i + 15] == vacio) {
                                if (!esObligatorio) {
                                    this.ingresarJugada(movimientos[cnt++], opc[1], i, i + 15, 0);
                                }
                            } else if (tablero[i + 15] * jugador < vacio) {
                                this.ingresarJugada(movimientosObligados[cnto++], opc[1], i, i + 15, 0);
                                esObligatorio = true;
                            }
                        }
                        if (i > 15 && i % 8 < 7) {
                            if (tablero[i - 15] == vacio) {
                                if (!esObligatorio) {
                                    this.ingresarJugada(movimientos[cnt++], opc[1], i, i - 15, 0);
                                }
                            } else if (tablero[i - 15] * jugador < vacio) {
                                this.ingresarJugada(movimientosObligados[cnto++], opc[1], i, i - 15, 0);
                                esObligatorio = true;
                            }
                        }
                        //+17 -17
                        if (i < 48 && i % 8 < 7) {
                            if (tablero[i + 17] == vacio) {
                                if (!esObligatorio) {
                                    this.ingresarJugada(movimientos[cnt++], opc[1], i, i + 17, 0);
                                }
                            } else if (tablero[i + 17] * jugador < vacio) {
                                this.ingresarJugada(movimientosObligados[cnto++], opc[1], i, i + 17, 0);
                                esObligatorio = true;
                            }
                        }
                        if (i > 15 && i % 8 > 0) {
                            if (tablero[i - 17] == vacio) {
                                if (!esObligatorio) {
                                    this.ingresarJugada(movimientos[cnt++], opc[1], i, i - 17, 0);
                                }
                            } else if (tablero[i - 17] * jugador < vacio) {
                                this.ingresarJugada(movimientosObligados[cnto++], opc[1], i, i - 17, 0);
                                esObligatorio = true;
                            }
                        }
                        movimientos[_cabeceraJugadas][_cantidadJugadas] = cnt;
                        movimientosObligados[_cabeceraJugadas][_cantidadJugadas] = cnto;
                    } else if (ficha == opc[2]) {
                        esObligatorio = this.buscarMovimientosDiagonal(tablero, i, jugador, true, opc[2], null, esc,
                                movimientos, movimientosObligados, esObligatorio);
                        cnt = movimientos[_cabeceraJugadas][_cantidadJugadas];
                        cnto = movimientosObligados[_cabeceraJugadas][_cantidadJugadas];
                    } else if (ficha == opc[3]) {
                        esObligatorio = this.buscarMovimientosHorizontalVertical(tablero, i, jugador, true, opc[3], null, esc,
                                movimientos, movimientosObligados, esObligatorio);
                        cnt = movimientos[_cabeceraJugadas][_cantidadJugadas];
                        cnto = movimientosObligados[_cabeceraJugadas][_cantidadJugadas];
                    } else if (ficha == opc[4]) {
                        esObligatorio = this.buscarMovimientosDiagonal(tablero, i, jugador, true, opc[4], null, esc,
                                movimientos, movimientosObligados, esObligatorio);
                        esObligatorio = this.buscarMovimientosHorizontalVertical(tablero, i, jugador, true, opc[4], null, esc,
                                movimientos, movimientosObligados, esObligatorio);
                        cnt = movimientos[_cabeceraJugadas][_cantidadJugadas];
                        cnto = movimientosObligados[_cabeceraJugadas][_cantidadJugadas];
                    } else if (ficha == opc[5]) {
                        esObligatorio = this.buscarMovimientosDiagonal(tablero, i, jugador, false, opc[5], amenazasrival, esc,
                                movimientos, movimientosObligados, esObligatorio);
                        esObligatorio = this.buscarMovimientosHorizontalVertical(tablero, i, jugador, false, opc[5], amenazasrival, esc,
                                movimientos, movimientosObligados, esObligatorio);
                        cnt = movimientos[_cabeceraJugadas][_cantidadJugadas];
                        cnto = movimientosObligados[_cabeceraJugadas][_cantidadJugadas];
                        if (enroquecorto && !esObligatorio) {
                            switch (jugador) {
                                case white:
                                    if (i == 4 && tablero[5] == vacio && tablero[6] == vacio && tablero[7] == opc[3]) {
                                        if (!util.siArrayContiene(amenazasrival, 4) && !util.siArrayContiene(amenazasrival, 5) && !util.siArrayContiene(amenazasrival, 6)) {
                                            this.ingresarJugada(movimientos[cnt++], opc[5], i, 6, 0);
                                        }
                                    }
                                    break;
                                case black:
                                    if (i == 60 && tablero[61] == vacio && tablero[62] == vacio && tablero[63] == opc[3]) {
                                        if (!util.siArrayContiene(amenazasrival, 60) && !util.siArrayContiene(amenazasrival, 61) && !util.siArrayContiene(amenazasrival, 62)) {
                                            this.ingresarJugada(movimientos[cnt++], opc[5], i, 62, 0);
                                        }
                                    }
                                    break;
                            }
                            movimientos[_cabeceraJugadas][_cantidadJugadas] = cnt;
                        }
                        if (enroquelargo && !esObligatorio) {
                            switch (jugador) {
                                case white:
                                    if (i == 4 && tablero[3] == vacio && tablero[2] == vacio && tablero[1] == vacio && tablero[0] == opc[3]) {
                                        if (!util.siArrayContiene(amenazasrival, 4) && !util.siArrayContiene(amenazasrival, 3) && !util.siArrayContiene(amenazasrival, 2)) {
                                            this.ingresarJugada(movimientos[cnt++], opc[5], i, 2, 0);
                                        }
                                    }
                                    break;
                                case black:
                                    if (i == 60 && tablero[59] == vacio && tablero[58] == vacio && tablero[57] == vacio && tablero[56] == opc[3]) {
                                        if (!util.siArrayContiene(amenazasrival, 60) && !util.siArrayContiene(amenazasrival, 59) && !util.siArrayContiene(amenazasrival, 58)) {
                                            this.ingresarJugada(movimientos[cnt++], opc[5], i, 58, 0);
                                        }
                                    }
                                    break;
                            }
                            movimientos[_cabeceraJugadas][_cantidadJugadas] = cnt;
                        }
                    }
                }
            }
            //ordenar jugadas
            if (esObligatorio) {
                movimientosObligados[_cabeceraJugadas][_tieneJugadasObligatorias] = 1;
                jugadas = eslocal ? util.ordenarCapturas(movimientosObligados, amenazasrival) : movimientosObligados;
            } else {
                int _pking = opc_rival[5];
                int[] amenazas = this.devolverCasillasAmenazadas(tablero, jugador, _pking, opc, true);
                int p_king = util.devuelvePosicionRey(tablero, rival);
                jugadas = eslocal ? util.ordenarJugadasLocal(movimientos, tablero, amenazas, amenazasrival, jugador, p_king) : movimientos;
            }
        }

        return jugadas;
    }

    private boolean buscarMovimientosDiagonal(int[] tablero, int posicion,
            int color, boolean esRecursivo, int pieza, int[] amenazas, int[] esc,
            int[][] movimientos, int[][] movimientosObligados, boolean esObligatorio) {

        int factor = 1;
        int val;
        int cnt = movimientos[0][0];
        int cnto = movimientosObligados[0][0];
        boolean a7 = true,
                b7 = true,
                a9 = true,
                b9 = true;
        do {
            if (a7) {
                val = posicion - (7 * factor);
                if (val % 8 > 0 && (esc == null || esc[diagonalInferiorDerecha] == 1)) {
                    if (tablero[val] == vacio) {
                        if (!esObligatorio) {
                            if (!esRecursivo) {
                                if (!util.siArrayContiene(amenazas, val)) {
                                    this.ingresarJugada(movimientos[cnt++], pieza, posicion, val, 0);
                                }
                            } else {
                                this.ingresarJugada(movimientos[cnt++], pieza, posicion, val, 0);
                            }
                        }
                    } else {
                        if (tablero[val] * color < vacio) {
                            if (!esRecursivo) {
                                if (!util.siArrayContiene(amenazas, val)) {
                                    this.ingresarJugada(movimientosObligados[cnto++], pieza, posicion, val, 0);
                                    esObligatorio = true;
                                }
                            } else {
                                this.ingresarJugada(movimientosObligados[cnto++], pieza, posicion, val, 0);
                                esObligatorio = true;
                            }
                        }
                        a7 = false;
                    }
                } else {
                    a7 = false;
                }
            }
            if (b7) {
                val = posicion + (7 * factor);
                if (val < 64 && val % 8 < 7 && (esc == null || esc[diagonalSuperiorIzquierda] == 1)) {
                    if (tablero[val] == vacio) {
                        if (!esObligatorio) {
                            if (!esRecursivo) {
                                if (!util.siArrayContiene(amenazas, val)) {
                                    this.ingresarJugada(movimientos[cnt++], pieza, posicion, val, 0);
                                }
                            } else {
                                this.ingresarJugada(movimientos[cnt++], pieza, posicion, val, 0);
                            }
                        }
                    } else {
                        if (tablero[val] * color < vacio) {
                            if (!esRecursivo) {
                                if (!util.siArrayContiene(amenazas, val)) {
                                    this.ingresarJugada(movimientosObligados[cnto++], pieza, posicion, val, 0);
                                    esObligatorio = true;
                                }
                            } else {
                                this.ingresarJugada(movimientosObligados[cnto++], pieza, posicion, val, 0);
                                esObligatorio = true;
                            }
                        }
                        b7 = false;
                    }
                } else {
                    b7 = false;
                }
            }
            if (a9) {
                val = posicion - (9 * factor);
                if (val >= 0 && val % 8 < 7 && (esc == null || esc[diagonalInferiorIzquierda] == 1)) {
                    if (tablero[val] == vacio) {
                        if (!esObligatorio) {
                            if (!esRecursivo) {
                                if (!util.siArrayContiene(amenazas, val)) {
                                    this.ingresarJugada(movimientos[cnt++], pieza, posicion, val, 0);
                                }
                            } else {
                                this.ingresarJugada(movimientos[cnt++], pieza, posicion, val, 0);
                            }
                        }
                    } else {
                        if (tablero[val] * color < vacio) {
                            if (!esRecursivo) {
                                if (!util.siArrayContiene(amenazas, val)) {
                                    this.ingresarJugada(movimientosObligados[cnto++], pieza, posicion, val, 0);
                                    esObligatorio = true;
                                }
                            } else {
                                this.ingresarJugada(movimientosObligados[cnto++], pieza, posicion, val, 0);
                                esObligatorio = true;
                            }
                        }
                        a9 = false;
                    }
                } else {
                    a9 = false;
                }
            }
            if (b9) {
                val = posicion + (9 * factor);
                if (val < 64 && val % 8 > 0 && (esc == null || esc[diagonalSuperiorDerecha] == 1)) {
                    if (tablero[val] == vacio) {
                        if (!esObligatorio) {
                            if (!esRecursivo) {
                                if (!util.siArrayContiene(amenazas, val)) {
                                    this.ingresarJugada(movimientos[cnt++], pieza, posicion, val, 0);
                                }
                            } else {
                                this.ingresarJugada(movimientos[cnt++], pieza, posicion, val, 0);
                            }
                        }
                    } else {
                        if (tablero[val] * color < vacio) {
                            if (!esRecursivo) {
                                if (!util.siArrayContiene(amenazas, val)) {
                                    this.ingresarJugada(movimientosObligados[cnto++], pieza, posicion, val, 0);
                                    esObligatorio = true;
                                }
                            } else {
                                this.ingresarJugada(movimientosObligados[cnto++], pieza, posicion, val, 0);
                                esObligatorio = true;
                            }
                        }
                        b9 = false;
                    }
                } else {
                    b9 = false;
                }
            }
            factor++;
        } while ((a7 || b7 || a9 || b9) && factor < 8 && esRecursivo);

        movimientos[0][0] = cnt;
        movimientosObligados[0][0] = cnto;

        return esObligatorio;
    }

    private boolean buscarMovimientosHorizontalVertical(int[] tablero,
            int posicion, int color, boolean esRecursivo, int pieza, int[] amenazas, int[] esc,
            int[][] movimientos, int[][] movimientosObligados, boolean esObligatorio) {

        int factor = 1;
        int val;
        int cnt = movimientos[0][0];
        int cnto = movimientosObligados[0][0];
        boolean a1 = true,
                b1 = true,
                a8 = true,
                b8 = true;
        do {
            if (a1) {
                val = posicion - (1 * factor);
                if (val >= 0 && val % 8 < 7 && (esc == null || esc[horizontalIzquierda] == 1)) {
                    if (tablero[val] == vacio) {
                        if (!esObligatorio) {
                            if (!esRecursivo) {
                                if (!util.siArrayContiene(amenazas, val)) {
                                    this.ingresarJugada(movimientos[cnt++], pieza, posicion, val, 0);
                                }
                            } else {
                                this.ingresarJugada(movimientos[cnt++], pieza, posicion, val, 0);
                            }
                        }
                    } else {
                        if (tablero[val] * color < vacio) {
                            if (!esRecursivo) {
                                if (!util.siArrayContiene(amenazas, val)) {
                                    this.ingresarJugada(movimientosObligados[cnto++], pieza, posicion, val, 0);
                                    esObligatorio = true;
                                }
                            } else {
                                this.ingresarJugada(movimientosObligados[cnto++], pieza, posicion, val, 0);
                                esObligatorio = true;
                            }
                        }
                        a1 = false;
                    }
                } else {
                    a1 = false;
                }
            }
            if (b1) {
                val = posicion + (1 * factor);
                if (val % 8 > 0 && (esc == null || esc[horizontalDerecha] == 1)) {
                    if (tablero[val] == vacio) {
                        if (!esObligatorio) {
                            if (!esRecursivo) {
                                if (!util.siArrayContiene(amenazas, val)) {
                                    this.ingresarJugada(movimientos[cnt++], pieza, posicion, val, 0);
                                }
                            } else {
                                this.ingresarJugada(movimientos[cnt++], pieza, posicion, val, 0);
                            }
                        }
                    } else {
                        if (tablero[val] * color < vacio) {
                            if (!esRecursivo) {
                                if (!util.siArrayContiene(amenazas, val)) {
                                    this.ingresarJugada(movimientosObligados[cnto++], pieza, posicion, val, 0);
                                    esObligatorio = true;
                                }
                            } else {
                                this.ingresarJugada(movimientosObligados[cnto++], pieza, posicion, val, 0);
                                esObligatorio = true;
                            }
                        }
                        b1 = false;
                    }
                } else {
                    b1 = false;
                }
            }
            if (a8) {
                val = posicion - (8 * factor);
                if (val >= 0 && (esc == null || esc[verticalInferior] == 1)) {
                    if (tablero[val] == vacio) {
                        if (!esObligatorio) {
                            if (!esRecursivo) {
                                if (!util.siArrayContiene(amenazas, val)) {
                                    this.ingresarJugada(movimientos[cnt++], pieza, posicion, val, 0);
                                }
                            } else {
                                this.ingresarJugada(movimientos[cnt++], pieza, posicion, val, 0);
                            }
                        }
                    } else {
                        if (tablero[val] * color < vacio) {
                            if (!esRecursivo) {
                                if (!util.siArrayContiene(amenazas, val)) {
                                    this.ingresarJugada(movimientosObligados[cnto++], pieza, posicion, val, 0);
                                    esObligatorio = true;
                                }
                            } else {
                                this.ingresarJugada(movimientosObligados[cnto++], pieza, posicion, val, 0);
                                esObligatorio = true;
                            }
                        }
                        a8 = false;
                    }
                } else {
                    a8 = false;
                }
            }
            if (b8) {
                val = posicion + (8 * factor);
                if (val < 64 && (esc == null || esc[verticalSuperior] == 1)) {
                    if (tablero[val] == vacio) {
                        if (!esObligatorio) {
                            if (!esRecursivo) {
                                if (!util.siArrayContiene(amenazas, val)) {
                                    this.ingresarJugada(movimientos[cnt++], pieza, posicion, val, 0);
                                }
                            } else {
                                this.ingresarJugada(movimientos[cnt++], pieza, posicion, val, 0);
                            }
                        }
                    } else {
                        if (tablero[val] * color < vacio) {
                            if (!esRecursivo) {
                                if (!util.siArrayContiene(amenazas, val)) {
                                    this.ingresarJugada(movimientosObligados[cnto++], pieza, posicion, val, 0);
                                    esObligatorio = true;
                                }
                            } else {
                                this.ingresarJugada(movimientosObligados[cnto++], pieza, posicion, val, 0);
                                esObligatorio = true;
                            }
                        }
                        b8 = false;
                    }
                } else {
                    b8 = false;
                }
            }
            factor++;
        } while ((a1 || b1 || a8 || b8) && factor < 8 && esRecursivo);

        movimientos[0][0] = cnt;
        movimientosObligados[0][0] = cnto;

        return esObligatorio;
    }

    public int[] devolverCasillasAmenazadas(int[] tablero, int color, int pking, int[] opc, boolean esRival) {
        int[] amenazas = esRival ? casillasamenazadasrival : casillasamenazadas;
        int c = 1;
        int ficha;

        amenazas[0] = 0;

        for (int i = 0; i < 64; i++) {
            ficha = tablero[i];

            if (ficha * color > 0) {
                if (ficha == opc[0]) {
                    switch (color) {
                        case white:
                            if (i % 8 != 0) {
                                amenazas[c++] = (tablero[i + 7] == king) ? 100 + i : i + 7;
                            }
                            if ((i + 1) % 8 != 0) {
                                amenazas[c++] = (tablero[i + 9] == king) ? 100 + i : i + 9;
                            }
                            break;
                        case black:
                            if ((i + 1) % 8 != 0) {
                                amenazas[c++] = (tablero[i - 7] == KING) ? 100 + i : i - 7;
                            }
                            if (i % 8 != 0) {
                                amenazas[c++] = (tablero[i - 9] == KING) ? 100 + i : i - 9;
                            }
                            break;
                    }
                } else if (ficha == opc[1]) {
                    //+6 -6
                    if ((i < 56 && i % 8 > 1)) {
                        amenazas[c++] = (tablero[i + 6] == pking) ? 100 + i : i + 6;
                    }
                    if (i > 7 && i % 8 < 6) {
                        amenazas[c++] = (tablero[i - 6] == pking) ? 100 + i : i - 6;
                    }
                    //+10 -10
                    if (i < 56 && i % 8 < 6) {
                        amenazas[c++] = (tablero[i + 10] == pking) ? 100 + i : i + 10;
                    }
                    if (i > 7 && i % 8 > 1) {
                        amenazas[c++] = (tablero[i - 10] == pking) ? 100 + i : i - 10;
                    }
                    //+15 -15
                    if (i < 48 && i % 8 > 0) {
                        amenazas[c++] = (tablero[i + 15] == pking) ? 100 + i : i + 15;
                    }
                    if (i > 15 && i % 8 < 7) {
                        amenazas[c++] = (tablero[i - 15] == pking) ? 100 + i : i - 15;
                    }
                    //+17 -17
                    if (i < 48 && i % 8 < 7) {
                        amenazas[c++] = (tablero[i + 17] == pking) ? 100 + i : i + 17;
                    }
                    if ((i > 15 && i % 8 > 0)) {
                        amenazas[c++] = (tablero[i - 17] == pking) ? 100 + i : i - 17;
                    }
                } else if (ficha == opc[2]) {
                    c = this.buscarAmenazasDiagonal(tablero, i, true, amenazas, pking, c);
                } else if (ficha == opc[3]) {
                    c = this.buscarAmenazasHorizontalVertical(tablero, i, true, amenazas, pking, c);
                } else if (ficha == opc[4]) {
                    c = this.buscarAmenazasDiagonal(tablero, i, true, amenazas, pking, c);
                    c = this.buscarAmenazasHorizontalVertical(tablero, i, true, amenazas, pking, c);
                } else if (ficha == opc[5]) {
                    c = this.buscarAmenazasDiagonal(tablero, i, false, amenazas, pking, c);
                    c = this.buscarAmenazasHorizontalVertical(tablero, i, false, amenazas, pking, c);
                }
            }
        }

        amenazas[0] = c;

        return amenazas;
    }

    private int buscarAmenazasDiagonal(int[] tablero, int pos, boolean esRecursivo, int[] amenazas, int pking, int c) {

        int factor = 1;
        int val;
        boolean a7 = true,
                b7 = true,
                a9 = true,
                b9 = true;
        do {
            if (a7) {
                val = pos - (7 * factor);
                if (val % 8 > 0) {
                    if (tablero[val] != vacio && !(tablero[val] == pking)) {
                        a7 = false;
                    }
                    if (tablero[val] == pking) {
                        amenazas[c++] = 100 + pos;
                    } else {
                        amenazas[c++] = val;
                    }
                } else {
                    a7 = false;
                }
            }
            if (b7) {
                val = pos + (7 * factor);
                if (val < 64 && val % 8 < 7) {
                    if (tablero[val] != vacio && !(tablero[val] == pking)) {
                        b7 = false;
                    }
                    if (tablero[val] == pking) {
                        amenazas[c++] = 100 + pos;
                    } else {
                        amenazas[c++] = val;
                    }
                } else {
                    b7 = false;
                }
            }
            if (a9) {
                val = pos - (9 * factor);
                if (val >= 0 && val % 8 < 7) {
                    if (tablero[val] != vacio && !(tablero[val] == pking)) {
                        a9 = false;
                    }
                    if (tablero[val] == pking) {
                        amenazas[c++] = 100 + pos;
                    } else {
                        amenazas[c++] = val;
                    }
                } else {
                    a9 = false;
                }
            }
            if (b9) {
                val = pos + (9 * factor);
                if (val < 64 && val % 8 > 0) {
                    if (tablero[val] != vacio && !(tablero[val] == pking)) {
                        b9 = false;
                    }
                    if (tablero[val] == pking) {
                        amenazas[c++] = 100 + pos;
                    } else {
                        amenazas[c++] = val;
                    }
                } else {
                    b9 = false;
                }
            }
            factor++;
        } while ((a7 || b7 || a9 || b9) && factor < 8 && esRecursivo);

        return c;
    }

    private int buscarAmenazasHorizontalVertical(int[] tablero, int pos, boolean esRecursivo, int[] amenazas, int pking, int c) {
        int factor = 1;
        int val;
        boolean a1 = true,
                b1 = true,
                a8 = true,
                b8 = true;
        do {
            if (a1) {
                val = pos - (1 * factor);
                if (val >= 0 && val % 8 < 7) {
                    if (tablero[val] != vacio && !(tablero[val] == pking)) {
                        a1 = false;
                    }
                    if (tablero[val] == pking) {
                        amenazas[c++] = 100 + pos;
                    } else {
                        amenazas[c++] = val;
                    }
                } else {
                    a1 = false;
                }
            }
            if (b1) {
                val = pos + (1 * factor);
                if (val % 8 > 0) {
                    if (tablero[val] != vacio && !(tablero[val] == pking)) {
                        b1 = false;
                    }
                    if (tablero[val] == pking) {
                        amenazas[c++] = 100 + pos;
                    } else {
                        amenazas[c++] = val;
                    }
                } else {
                    b1 = false;
                }
            }
            if (a8) {
                val = pos - (8 * factor);
                if (val >= 0) {
                    if (tablero[val] != vacio && !(tablero[val] == pking)) {
                        a8 = false;
                    }
                    if (tablero[val] == pking) {
                        amenazas[c++] = 100 + pos;
                    } else {
                        amenazas[c++] = val;
                    }
                } else {
                    a8 = false;
                }
            }
            if (b8) {
                val = pos + (8 * factor);
                if (val < 64) {
                    if (tablero[val] != vacio && !(tablero[val] == pking)) {
                        b8 = false;
                    }
                    if (tablero[val] == pking) {
                        amenazas[c++] = 100 + pos;
                    } else {
                        amenazas[c++] = val;
                    }
                } else {
                    b8 = false;
                }
            }
            factor++;
        } while ((a1 || b1 || a8 || b8) && factor < 8 && esRecursivo);

        return c;
    }

    public int[][] buscarJugadasenJaque(int[] tablero, int[] amenazas, int color, int jug_ini, int jug_fin,
            int[][] amenazasescondidas, int posicion_rey, int pos_jaque, int rival, int[] opc, int[] opc_rival) {

        int[][] jugadas;
        boolean esObligatorio = false;

        //buscamos los movimientos del rey
        util.iniciarCabeceraJugada(movimientos[_cabeceraJugadas]);
        util.iniciarCabeceraJugada(movimientosObligados[_cabeceraJugadas]);

        esObligatorio = this.buscarMovimientosHorizontalVertical(tablero, posicion_rey, color, false, opc[5], amenazas, null,
                movimientos, movimientosObligados, esObligatorio);
        esObligatorio = this.buscarMovimientosDiagonal(tablero, posicion_rey, color, false, opc[5], amenazas, null,
                movimientos, movimientosObligados, esObligatorio);

        if (pos_jaque == 100) {
            if (esObligatorio) {
                movimientosObligados[_cabeceraJugadas][_tieneJugadasObligatorias] = 1;
                jugadas = movimientosObligados;
            } else {
                movimientos[_cabeceraJugadas][_hayJaque] = 1;
                jugadas = movimientos;
            }
        } else {
            //buscar las jugadas que pueden cubrir el jaque o comer la pieza del jaque
            int[][] defensasjaque = this.devolverCasillasDefensivas(tablero, color, jug_ini, jug_fin, amenazasescondidas, opc);
            int cnto = movimientosObligados[0][0];
            int[] d;
            int fin;

            //buscamos defensas que maten el jaque
            for (int k = 1; k < defensasjaque[0][0]; k++) {
                d = defensasjaque[k];
                fin = d[2];

                if (fin > 99) {
                    if (jug_fin == pos_jaque) {
                        this.ingresarJugada(movimientosObligados[cnto++], d[0], d[1], fin - 100, d[3]);
                    }
                } else {
                    if (fin == pos_jaque) {
                        this.ingresarJugada(movimientosObligados[cnto++], d[0], d[1], d[2], d[3]);
                    }
                }
            }

            movimientosObligados[0][0] = cnto;

            if (cnto > 1) {
                movimientosObligados[_cabeceraJugadas][_tieneJugadasObligatorias] = 1;
                jugadas = movimientosObligados;
            } else {
                int cnt = movimientos[0][0];
                movimientos[_cabeceraJugadas][_hayJaque] = 1;
                jugadas = movimientos;

                //buscamos jugadas que obstruyan el jaque si la ficha que da jaque es bishop, rook o queen
                if (tablero[pos_jaque] == opc_rival[2] || tablero[pos_jaque] == opc_rival[3] || tablero[pos_jaque] == opc_rival[4]) {
                    int val1, val2, val3 = 0;
                    int diff = posicion_rey - pos_jaque;

                    diff = (diff < 0) ? -diff : diff;

                    if (posicion_rey < pos_jaque) {
                        val1 = posicion_rey;
                        val2 = pos_jaque;
                    } else { //  pos_jaque < posicion_rey
                        val1 = pos_jaque;
                        val2 = posicion_rey;
                    }
                    if (diff < 7 || (diff == 7 && val1 % 8 == 0)) {
                        val3 = 1;
                    } else if (diff % 7 == 0) {
                        val3 = 7;
                    } else if (diff % 8 == 0) {
                        val3 = 8;
                    } else if (diff % 9 == 0) {
                        val3 = 9;
                    }
                    if (val3 > 0) {
                        for (int i = val1 + val3; i < val2; i = i + val3) {
                            for (int p = 1; p < defensasjaque[0][0]; p++) {
                                d = defensasjaque[p];
                                if (d[2] == i) {
                                    this.ingresarJugada(jugadas[cnt++], d[0], d[1], d[2], d[3]);
                                }
                            }
                        }
                    }
                }
                jugadas[0][0] = cnt;
            }
        }

        return jugadas;
    }

    private int[][] devolverCasillasDefensivas(int[] tablero, int color,
            int jug_ini, int jug_fin, int[][] amenazasescondidas, int[] opc) {

        int[] esc;
        int ficha;
        int cnt = 1;

        util.iniciarCabeceraJugada(defensas[_cabeceraJugadas]);

        for (int i = 0; i < 64; i++) {
            ficha = tablero[i];

            if (ficha * color > 0) {
                esc = util.buscarIndiceAmenazaEscondida(amenazasescondidas, i);

                if (esc != null && esc[sinMovimientos] == 1) {
                    continue;
                }

                if (ficha == opc[0]) {
                    switch (color) {
                        case white:
                            if (tablero[i + 8] == vacio && (esc == null || esc[verticalSuperior] == 1)) {
                                if (i + 8 > 55 && i + 8 < 64) {
                                    this.ingresarJugada(defensas[cnt++], opc[0], i, i + 8, QUEEN);
                                    this.ingresarJugada(defensas[cnt++], opc[0], i, i + 8, ROOK);
                                    this.ingresarJugada(defensas[cnt++], opc[0], i, i + 8, BISHOP);
                                    this.ingresarJugada(defensas[cnt++], opc[0], i, i + 8, KNIGHT);
                                } else {
                                    this.ingresarJugada(defensas[cnt++], opc[0], i, i + 8, 0);
                                    if ((i >= 8 && i <= 15) && tablero[i + 16] == vacio) {
                                        this.ingresarJugada(defensas[cnt++], opc[0], i, i + 16, 0);
                                    }
                                }
                            }
                            if (i % 8 != 0 && (esc == null || esc[diagonalSuperiorIzquierda] == 1)) {
                                if (tablero[i + 7] != vacio) {
                                    if (tablero[i + 7] > vacio) {
                                        if (i + 7 > 55 && i + 7 < 64) {
                                            this.ingresarJugada(defensas[cnt++], opc[0], i, i + 7, QUEEN);
                                            this.ingresarJugada(defensas[cnt++], opc[0], i, i + 7, ROOK);
                                            this.ingresarJugada(defensas[cnt++], opc[0], i, i + 7, BISHOP);
                                            this.ingresarJugada(defensas[cnt++], opc[0], i, i + 7, KNIGHT);
                                        } else {
                                            this.ingresarJugada(defensas[cnt++], opc[0], i, i + 7, 0);
                                        }
                                    }
                                } else {
                                    if (jug_ini != -1 && jug_fin != -1 && tablero[jug_fin] == pawn) {
                                        if (jug_ini >= 48 && jug_ini <= 55 && jug_fin == jug_ini - 16 && jug_fin == i - 1) {
                                            this.ingresarJugada(defensas[cnt++], opc[0], i, 100 + i + 7, 0);
                                        }
                                    }
                                }
                            }
                            if ((i + 1) % 8 != 0 && (esc == null || esc[diagonalSuperiorDerecha] == 1)) {
                                if (tablero[i + 9] != vacio) {
                                    if (tablero[i + 9] > vacio) {
                                        if (i + 9 > 55 && i + 9 < 64) {
                                            this.ingresarJugada(defensas[cnt++], opc[0], i, i + 9, QUEEN);
                                            this.ingresarJugada(defensas[cnt++], opc[0], i, i + 9, ROOK);
                                            this.ingresarJugada(defensas[cnt++], opc[0], i, i + 9, BISHOP);
                                            this.ingresarJugada(defensas[cnt++], opc[0], i, i + 9, KNIGHT);
                                        } else {
                                            this.ingresarJugada(defensas[cnt++], opc[0], i, i + 9, 0);
                                        }
                                    }
                                } else {
                                    if (jug_ini != -1 && jug_fin != -1 && tablero[jug_fin] == pawn) {
                                        if (jug_ini >= 48 && jug_ini <= 55 && jug_fin == jug_ini - 16 && jug_fin == i + 1) {
                                            this.ingresarJugada(defensas[cnt++], opc[0], i, 100 + i + 9, 0);
                                        }
                                    }
                                }
                            }
                            break;
                        case black:
                            if (tablero[i - 8] == vacio && (esc == null || esc[verticalInferior] == 1)) {
                                if (i - 8 >= 0 && i - 8 < 8) {
                                    this.ingresarJugada(defensas[cnt++], opc[0], i, i - 8, queen);
                                    this.ingresarJugada(defensas[cnt++], opc[0], i, i - 8, rook);
                                    this.ingresarJugada(defensas[cnt++], opc[0], i, i - 8, bishop);
                                    this.ingresarJugada(defensas[cnt++], opc[0], i, i - 8, knight);
                                } else {
                                    this.ingresarJugada(defensas[cnt++], opc[0], i, i - 8, 0);
                                    if ((i >= 48 && i <= 55) && tablero[i - 16] == vacio) {
                                        this.ingresarJugada(defensas[cnt++], opc[0], i, i - 16, 0);
                                    }
                                }
                            }
                            if ((i + 1) % 8 != 0 && (esc == null || esc[diagonalInferiorDerecha] == 1)) {
                                if (tablero[i - 7] != vacio) {
                                    if (tablero[i - 7] < vacio) {
                                        if (i - 7 > 0 && i - 7 < 8) {
                                            this.ingresarJugada(defensas[cnt++], opc[0], i, i - 7, queen);
                                            this.ingresarJugada(defensas[cnt++], opc[0], i, i - 7, rook);
                                            this.ingresarJugada(defensas[cnt++], opc[0], i, i - 7, bishop);
                                            this.ingresarJugada(defensas[cnt++], opc[0], i, i - 7, knight);
                                        } else {
                                            this.ingresarJugada(defensas[cnt++], opc[0], i, i - 7, 0);
                                        }
                                    }
                                } else {
                                    if (jug_ini != -1 && jug_fin != -1 && tablero[jug_fin] == PAWN) {
                                        if (jug_ini >= 8 && jug_ini <= 15 && jug_fin == jug_ini + 16 && jug_fin == i + 1) {
                                            this.ingresarJugada(defensas[cnt++], opc[0], i, 100 + i - 7, 0);
                                        }
                                    }
                                }
                            }
                            if (i % 8 != 0 && (esc == null || esc[diagonalInferiorIzquierda] == 1)) {
                                if (tablero[i - 9] != vacio) {
                                    if (tablero[i - 9] < vacio) {
                                        if (i - 9 >= 0 && i - 9 < 8) {
                                            this.ingresarJugada(defensas[cnt++], opc[0], i, i - 9, queen);
                                            this.ingresarJugada(defensas[cnt++], opc[0], i, i - 9, rook);
                                            this.ingresarJugada(defensas[cnt++], opc[0], i, i - 9, bishop);
                                            this.ingresarJugada(defensas[cnt++], opc[0], i, i - 9, knight);
                                        } else {
                                            this.ingresarJugada(defensas[cnt++], opc[0], i, i - 9, 0);
                                        }
                                    }
                                } else {
                                    if (jug_ini != -1 && jug_fin != -1 && tablero[jug_fin] == PAWN) {
                                        if (jug_ini >= 8 && jug_ini <= 15 && jug_fin == jug_ini + 16 && jug_fin == i - 1) {
                                            this.ingresarJugada(defensas[cnt++], opc[0], i, 100 + i - 9, 0);
                                        }
                                    }
                                }
                            }
                            break;
                    }
                    defensas[0][0] = cnt;
                } else if (ficha == opc[1]) {
                    //+6 -6
                    if (i < 56 && i % 8 > 1) {
                        if (tablero[i + 6] == vacio) {
                            this.ingresarJugada(defensas[cnt++], opc[1], i, i + 6, 0);
                        } else if (tablero[i + 6] * color < vacio) {
                            this.ingresarJugada(defensas[cnt++], opc[1], i, i + 6, 0);
                        }
                    }
                    if (i > 7 && i % 8 < 6) {
                        if (tablero[i - 6] == vacio) {
                            this.ingresarJugada(defensas[cnt++], opc[1], i, i - 6, 0);
                        } else if (tablero[i - 6] != color) {
                            this.ingresarJugada(defensas[cnt++], opc[1], i, i - 6, 0);
                        }
                    }
                    //+10 -10
                    if (i < 56 && i % 8 < 6) {
                        if (tablero[i + 10] == vacio) {
                            this.ingresarJugada(defensas[cnt++], opc[1], i, i + 10, 0);
                        } else if (tablero[i + 10] * color < vacio) {
                            this.ingresarJugada(defensas[cnt++], opc[1], i, i + 10, 0);
                        }
                    }
                    if (i > 7 && i % 8 > 1) {
                        if (tablero[i - 10] == vacio) {
                            this.ingresarJugada(defensas[cnt++], opc[1], i, i - 10, 0);
                        } else if (tablero[i - 10] * color < vacio) {
                            this.ingresarJugada(defensas[cnt++], opc[1], i, i - 10, 0);
                        }
                    }
                    //+15 -15
                    if (i < 48 && i % 8 > 0) {
                        if (tablero[i + 15] == vacio) {
                            this.ingresarJugada(defensas[cnt++], opc[1], i, i + 15, 0);
                        } else if (tablero[i + 15] * color < vacio) {
                            this.ingresarJugada(defensas[cnt++], opc[1], i, i + 15, 0);
                        }
                    }
                    if (i > 15 && i % 8 < 7) {
                        if (tablero[i - 15] == vacio) {
                            this.ingresarJugada(defensas[cnt++], opc[1], i, i - 15, 0);
                        } else if (tablero[i - 15] * color < vacio) {
                            this.ingresarJugada(defensas[cnt++], opc[1], i, i - 15, 0);
                        }
                    }
                    //+17 -17
                    if (i < 48 && i % 8 < 7) {
                        if (tablero[i + 17] == vacio) {
                            this.ingresarJugada(defensas[cnt++], opc[1], i, i + 17, 0);
                        } else if (tablero[i + 17] * color < vacio) {
                            this.ingresarJugada(defensas[cnt++], opc[1], i, i + 17, 0);
                        }
                    }
                    if (i > 15 && i % 8 > 0) {
                        if (tablero[i - 17] == vacio) {
                            this.ingresarJugada(defensas[cnt++], opc[1], i, i - 17, 0);
                        } else if (tablero[i - 17] * color < vacio) {
                            this.ingresarJugada(defensas[cnt++], opc[1], i, i - 17, 0);
                        }
                    }
                    defensas[0][0] = cnt;
                } else if (ficha == opc[2]) {
                    this.buscarDefensasDiagonal(tablero, i, color, opc[2], esc, defensas);
                    cnt = defensas[0][0];
                } else if (ficha == opc[3]) {
                    this.buscarDefensasHorizontalVertical(tablero, i, color, rook, esc, defensas);
                    cnt = defensas[0][0];
                } else if (ficha == opc[4]) {
                    this.buscarDefensasDiagonal(tablero, i, color, queen, esc, defensas);
                    this.buscarDefensasHorizontalVertical(tablero, i, color, queen, esc, defensas);
                    cnt = defensas[0][0];
                }
            }
        }

        return defensas;
    }

    private void buscarDefensasDiagonal(int[] tablero, int posicion, int color, int pieza, int[] esc, int[][] defensas) {

        int factor = 1;
        int val;
        int cnt = defensas[0][0];
        boolean a7 = true,
                b7 = true,
                a9 = true,
                b9 = true;
        do {
            if (a7) {
                val = posicion - (7 * factor);
                if (val % 8 > 0 && (esc == null || esc[diagonalInferiorDerecha] == 1)) {
                    if (tablero[val] == vacio) {
                        this.ingresarJugada(defensas[cnt++], pieza, posicion, val, 0);
                    } else {
                        if (tablero[val] * color < vacio) {
                            this.ingresarJugada(defensas[cnt++], pieza, posicion, val, 0);
                        }
                        a7 = false;
                    }
                } else {
                    a7 = false;
                }
            }
            if (b7) {
                val = posicion + (7 * factor);
                if (val < 64 && val % 8 < 7 && (esc == null || esc[diagonalSuperiorIzquierda] == 1)) {
                    if (tablero[val] == vacio) {
                        this.ingresarJugada(defensas[cnt++], pieza, posicion, val, 0);
                    } else {
                        if (tablero[val] * color < vacio) {
                            this.ingresarJugada(defensas[cnt++], pieza, posicion, val, 0);
                        }
                        b7 = false;
                    }
                } else {
                    b7 = false;
                }
            }
            if (a9) {
                val = posicion - (9 * factor);
                if (val >= 0 && val % 8 < 7 && (esc == null || esc[diagonalInferiorIzquierda] == 1)) {
                    if (tablero[val] == vacio) {
                        this.ingresarJugada(defensas[cnt++], pieza, posicion, val, 0);
                    } else {
                        if (tablero[val] * color < vacio) {
                            this.ingresarJugada(defensas[cnt++], pieza, posicion, val, 0);
                        }
                        a9 = false;
                    }
                } else {
                    a9 = false;
                }
            }
            if (b9) {
                val = posicion + (9 * factor);
                if (val < 64 && val % 8 > 0 && (esc == null || esc[diagonalSuperiorDerecha] == 1)) {
                    if (tablero[val] == vacio) {
                        this.ingresarJugada(defensas[cnt++], pieza, posicion, val, 0);
                    } else {
                        if (tablero[val] * color < vacio) {
                            this.ingresarJugada(defensas[cnt++], pieza, posicion, val, 0);
                        }
                        b9 = false;
                    }
                } else {
                    b9 = false;
                }
            }
            factor++;
        } while ((a7 || b7 || a9 || b9) && factor < 8);

        defensas[0][0] = cnt;
    }

    private void buscarDefensasHorizontalVertical(int[] tablero, int posicion,
            int color, int pieza, int[] esc, int[][] defensas) {

        int factor = 1;
        int val;
        int cnt = defensas[0][0];
        boolean a1 = true,
                b1 = true,
                a8 = true,
                b8 = true;
        do {
            if (a1) {
                val = posicion - (1 * factor);
                if (val >= 0 && val % 8 < 7 && (esc == null || esc[horizontalIzquierda] == 1)) {
                    if (tablero[val] == vacio) {
                        this.ingresarJugada(defensas[cnt++], pieza, posicion, val, 0);
                    } else {
                        if (tablero[val] * color < vacio) {
                            this.ingresarJugada(defensas[cnt++], pieza, posicion, val, 0);
                        }
                        a1 = false;
                    }
                } else {
                    a1 = false;
                }
            }
            if (b1) {
                val = posicion + (1 * factor);
                if (val % 8 > 0 && (esc == null || esc[horizontalDerecha] == 1)) {
                    if (tablero[val] == vacio) {
                        this.ingresarJugada(defensas[cnt++], pieza, posicion, val, 0);
                    } else {
                        if (tablero[val] * color < vacio) {
                            this.ingresarJugada(defensas[cnt++], pieza, posicion, val, 0);
                        }
                        b1 = false;
                    }
                } else {
                    b1 = false;
                }
            }
            if (a8) {
                val = posicion - (8 * factor);
                if (val >= 0 && (esc == null || esc[verticalInferior] == 1)) {
                    if (tablero[val] == vacio) {
                        this.ingresarJugada(defensas[cnt++], pieza, posicion, val, 0);
                    } else {
                        if (tablero[val] * color < vacio) {
                            this.ingresarJugada(defensas[cnt++], pieza, posicion, val, 0);
                        }
                        a8 = false;
                    }
                } else {
                    a8 = false;
                }
            }
            if (b8) {
                val = posicion + (8 * factor);
                if (val < 64 && (esc == null || esc[verticalSuperior] == 1)) {
                    if (tablero[val] == vacio) {
                        this.ingresarJugada(defensas[cnt++], pieza, posicion, val, 0);
                    } else {
                        if (tablero[val] * color < vacio) {
                            this.ingresarJugada(defensas[cnt++], pieza, posicion, val, 0);
                        }
                        b8 = false;
                    }
                } else {
                    b8 = false;
                }
            }
            factor++;
        } while ((a1 || b1 || a8 || b8) && factor < 8);

        defensas[0][0] = cnt;
    }

    public int[][] devolverCasillasAmenazadasEscondidas(int[] tablero, int color, int rival, int jug_ini, int jug_fin,
            int pos_king, int[] opc, int[] opc_rival) {
        int ficha;

        this.iniciarAmenazasEscondidas();
        
        for (int i = 0; i < 64; i++) {
            ficha = tablero[i];

            if (ficha * color > 0) {
                if (ficha == opc[2]) {
                    if (util.estanEnDiagonal(i, pos_king) && Math.abs(i - pos_king) > 10) {
                        this.poblarAmenazasEscondidasDiagonal(tablero, rival, i, pos_king, opc_rival);
                    }
                } else if (ficha == opc[3]) {
                    if ((util.enFila(i, pos_king) && Math.abs(i - pos_king) > 1) || (util.enColumna(i, pos_king) && Math.abs(i - pos_king) > 15)) {
                        this.poblarAmenazasEscondidasHorizontalVertical(tablero, rival,
                                i, pos_king, jug_ini, jug_fin, opc, opc_rival);
                    }
                } else if (ficha == opc[4]) {
                    if (util.estanEnDiagonal(i, pos_king) && Math.abs(i - pos_king) > 10) {
                        this.poblarAmenazasEscondidasDiagonal(tablero, rival, i, pos_king, opc_rival);
                    }
                    if ((util.enFila(i, pos_king) && Math.abs(i - pos_king) > 1) || (util.enColumna(i, pos_king) && Math.abs(i - pos_king) > 15)) {
                        this.poblarAmenazasEscondidasHorizontalVertical(tablero, rival,
                                i, pos_king, jug_ini, jug_fin, opc, opc_rival);
                    }
                }
            }
        }

        return escondidas;
    }

    private void poblarAmenazasEscondidasDiagonal(int[] tablero,
            int color_rival, int pos, int pos_king, int[] opc_rival) {
        int factor = 1;
        int cont = 0;
        int temporal = -1;
        int val;
        int ficha;
        int c;

        c = escondidas[0][indiceMovimiento];

        if (pos > pos_king) {
            if ((pos - pos_king) % 7 == 0 && pos - pos_king < 63) {
                val = pos - (7 * factor);
                do {
                    if (tablero[val] * color_rival > 0) {
                        cont++;
                        if (cont < 2) {
                            temporal = val;
                        } else {
                            temporal = -1;
                            break;
                        }
                    } else if (tablero[val] != vacio) {
                        temporal = -1;
                        break;
                    }
                    factor++;
                } while ((val = pos - (7 * factor)) != pos_king);

                if (temporal != -1) {
                    ficha = tablero[temporal];
                    if (ficha == opc_rival[1]
                            || ficha == opc_rival[3]) {
                        escondidas[c][sinMovimientos] = 1;
                    } else if (ficha == opc_rival[0]
                            || ficha == opc_rival[2]
                            || ficha == opc_rival[5]) {
                        escondidas[c][diagonalSuperiorIzquierda] = 1;
                        escondidas[c][diagonalInferiorDerecha] = 1;
                    }
                    escondidas[c++][indiceMovimiento] = temporal;
                }
            } else { //i-9
                val = pos - (9 * factor);
                do {
                    if (tablero[val] * color_rival > 0) {
                        cont++;
                        if (cont < 2) {
                            temporal = val;
                        } else {
                            temporal = -1;
                            break;
                        }
                    } else if (tablero[val] != vacio) {
                        temporal = -1;
                        break;
                    }
                    factor++;
                } while ((val = pos - (9 * factor)) != pos_king);

                if (temporal != -1) {
                    ficha = tablero[temporal];
                    if (ficha == opc_rival[1]
                            || ficha == opc_rival[3]) {
                        escondidas[c][sinMovimientos] = 1;
                    } else if (ficha == opc_rival[0]
                            || ficha == opc_rival[2]
                            || ficha == opc_rival[4]) {
                        escondidas[c][diagonalSuperiorDerecha] = 1;
                        escondidas[c][diagonalInferiorIzquierda] = 1;
                    }
                    escondidas[c++][indiceMovimiento] = temporal;
                }
            }
        } else { //pos_king > pos
            if ((pos_king - pos) % 7 == 0 && pos_king - pos < 63) {
                val = pos + (7 * factor);
                do {
                    if (tablero[val] * color_rival > 0) {
                        cont++;
                        if (cont < 2) {
                            temporal = val;
                        } else {
                            temporal = -1;
                            break;
                        }
                    } else if (tablero[val] != vacio) {
                        temporal = -1;
                        break;
                    }
                    factor++;
                } while ((val = pos + (7 * factor)) != pos_king);

                if (temporal != -1) {
                    ficha = tablero[temporal];
                    if (ficha == opc_rival[1]
                            || ficha == opc_rival[3]) {
                        escondidas[c][sinMovimientos] = 1;
                    } else if (ficha == opc_rival[0]
                            || ficha == opc_rival[2]
                            || ficha == opc_rival[4]) {
                        escondidas[c][diagonalSuperiorIzquierda] = 1;
                        escondidas[c][diagonalInferiorDerecha] = 1;
                    }
                    escondidas[c++][indiceMovimiento] = temporal;
                }
            } else { //i+9
                val = pos + (9 * factor);
                do {
                    if (tablero[val] * color_rival > 0) {
                        cont++;
                        if (cont < 2) {
                            temporal = val;
                        } else {
                            temporal = -1;
                            break;
                        }
                    } else if (tablero[val] != vacio) {
                        temporal = -1;
                        break;
                    }
                    factor++;
                } while ((val = pos + (9 * factor)) != pos_king);

                if (temporal != -1) {
                    ficha = tablero[temporal];
                    if (ficha == opc_rival[1]
                            || ficha == opc_rival[3]) {
                        escondidas[c][sinMovimientos] = 1;
                    } else if (ficha == opc_rival[0]
                            || ficha == opc_rival[2]
                            || ficha == opc_rival[4]) {
                        escondidas[c][diagonalSuperiorDerecha] = 1;
                        escondidas[c][diagonalInferiorIzquierda] = 1;
                    }
                    escondidas[c++][indiceMovimiento] = temporal;
                }
            }
        }

        escondidas[0][indiceMovimiento] = c;
    }

    private void poblarAmenazasEscondidasHorizontalVertical(int[] tablero,
            int color_rival, int pos, int pos_king, int jug_ini, int jug_fin, int[] opc, int[] opc_rival) {

        int factor = 1;
        int cont = 0;
        int temporal = -1;
        int tipo = -1;
        int val;
        int ficha;
        int c;

        c = escondidas[0][indiceMovimiento];

        if (pos > pos_king) {
            if (pos - pos_king > 1 && pos - pos_king < 8) {
                val = pos - factor;
                do {
                    if (tablero[val] * color_rival > 0) {
                        cont++;
                        if (cont < 2) {
                            temporal = val;
                            tipo = 0;
                        } else {
                            temporal = -1;
                            break;
                        }
                    } else if (tablero[val] != vacio) {
                        if (tablero[val] == opc[0] && val == jug_fin && Math.abs(jug_ini - jug_fin) == 16) {
                            if (cont == 1) {
                                if (tablero[val + 1] == opc[0]) {
                                    temporal = val + 1;
                                    tipo = 1;
                                } else {
                                    temporal = -1;
                                    break;
                                }
                            } else {//cont = 0
                                if (tablero[val - 1] == opc_rival[0]) {
                                    temporal = val - 1;
                                    tipo = 2;
                                    cont++;
                                    factor++;
                                } else {
                                    break;
                                }
                            }
                        } else {
                            temporal = -1;
                            break;
                        }
                    }
                    factor++;
                } while ((val = pos - factor) != pos_king);
                //asignar valor
                if (temporal != -1) {
                    switch (tipo) {
                        case 0:
                            ficha = tablero[temporal];
                            if (ficha == opc_rival[0]
                                    || ficha == opc_rival[1]
                                    || ficha == opc_rival[2]) {
                                escondidas[c][sinMovimientos] = 1;
                            } else if (ficha == opc_rival[3]
                                    || ficha == opc_rival[4]) {
                                escondidas[c][horizontalDerecha] = 1;
                                escondidas[c][horizontalIzquierda] = 1;
                            }
                            break;
                        case 1:
                        case 2:
                            escondidas[c][verticalInferior] = 1;
                            escondidas[c][verticalSuperior] = 1;
                            break;
                    }
                    escondidas[c++][indiceMovimiento] = temporal;
                }
            } else { //i-8
                val = pos - (8 * factor);
                do {
                    if (tablero[val] * color_rival > 0) {
                        cont++;
                        if (cont < 2) {
                            temporal = val;
                        } else {
                            temporal = -1;
                            break;
                        }
                    } else if (tablero[val] != vacio) {
                        temporal = -1;
                        break;
                    }
                    factor++;
                } while ((val = pos - (8 * factor)) != pos_king);

                if (temporal != -1) {
                    ficha = tablero[temporal];
                    if (ficha == opc_rival[1]
                            || ficha == opc_rival[2]) {
                        escondidas[c][sinMovimientos] = 1;
                    } else if (ficha == opc_rival[0]
                            || ficha == opc_rival[3]
                            || ficha == opc_rival[4]) {
                        escondidas[c][verticalInferior] = 1;
                        escondidas[c][verticalSuperior] = 1;
                    }
                    escondidas[c++][indiceMovimiento] = temporal;
                }
            }
        } else { //pos_king > pos
            if (pos_king - pos > 1 && pos_king - pos < 8) {
                val = pos + factor;
                do {
                    if (tablero[val] * color_rival > 0) {
                        cont++;
                        if (cont < 2) {
                            temporal = val;
                            tipo = 0;
                        } else {
                            temporal = -1;
                            break;
                        }
                    } else if (tablero[val] != vacio) {
                        if (tablero[val] == opc[0] && val == jug_fin && Math.abs(jug_ini - jug_fin) == 16) {
                            if (cont == 1) {
                                if (tablero[val - 1] == opc[0]) {
                                    temporal = val - 1;
                                    tipo = 1;
                                } else {
                                    temporal = -1;
                                    break;
                                }
                            } else {//cont = 0
                                if (tablero[val + 1] == opc_rival[0]) {
                                    temporal = val + 1;
                                    tipo = 2;
                                    cont++;
                                    factor++;
                                } else {
                                    break;
                                }
                            }
                        } else {
                            temporal = -1;
                            break;
                        }
                    }
                    factor++;
                } while ((val = pos + factor) != pos_king);
                //asignar valor
                if (temporal != -1) {
                    switch (tipo) {
                        case 0:
                            ficha = tablero[temporal];
                            if (ficha == opc_rival[0]
                                    || ficha == opc_rival[1]
                                    || ficha == opc_rival[2]) {
                                escondidas[c][sinMovimientos] = 1;
                            } else if (ficha == opc_rival[3]
                                    || ficha == opc_rival[4]) {
                                escondidas[c][horizontalDerecha] = 1;
                                escondidas[c][horizontalIzquierda] = 1;
                            }
                            break;
                        case 1:
                        case 2:
                            escondidas[c][verticalInferior] = 1;
                            escondidas[c][verticalSuperior] = 1;
                            break;
                    }
                    escondidas[c++][indiceMovimiento] = temporal;
                }
            } else { //i+8
                val = pos + (8 * factor);
                do {
                    if (tablero[val] * color_rival > 0) {
                        cont++;
                        if (cont < 2) {
                            temporal = val;
                        } else {
                            temporal = -1;
                            break;
                        }
                    } else if (tablero[val] != vacio) {
                        temporal = -1;
                        break;
                    }
                    factor++;
                } while ((val = pos + (8 * factor)) != pos_king);

                if (temporal != -1) {
                    ficha = tablero[temporal];
                    if (ficha == opc_rival[1]
                            || ficha == opc_rival[2]) {
                        escondidas[c][sinMovimientos] = 1;
                    } else if (ficha == opc_rival[0]
                            || ficha == opc_rival[3]
                            || ficha == opc_rival[4]) {
                        escondidas[c][verticalInferior] = 1;
                        escondidas[c][verticalSuperior] = 1;
                    }
                    escondidas[c++][indiceMovimiento] = temporal;
                }
            }
        }
        escondidas[0][indiceMovimiento] = c;
    }

    private void ingresarJugada(int[] j, int ficha, int ini, int fin, int prom) {
        j[0] = ficha;
        j[1] = ini;
        j[2] = fin;
        j[3] = prom;
    }
}
